﻿using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.XWPF.UserModel;

namespace CreateReport
{
    /// <summary>
    /// 所有自定义的报告和原始记录都在该类中处理
    /// </summary>
    public static class Common
    {
        /// <summary>
        /// 生成单样品报告
        /// </summary>
        /// <param name="report"></param>
        /// <param name="ResultList">结果列表</param>
        /// <param name="ReportTemplate">报告模板存放路径和名称。如果有多个不同的单样报告模版，根据模版名称在该函数中提供不同处理</param>
        /// <param name="saveDir">生成报告存放路径</param>
        /// <returns></returns>
        public static string CreateSingleReport(IQueryable<object> ResultList, string ReportTemplate, string saveDir, out string FileSize)
        {
            FileSize = "";
            if (!File.Exists(ReportTemplate))
                return "文件模板没找到！";

            XWPFDocument documentReport;
            using (FileStream fs = new FileStream(ReportTemplate, FileMode.Open, FileAccess.ReadWrite))
            {
                documentReport = new XWPFDocument(fs);
            }

            WriteToTableCell(documentReport, ResultList);

            var fileID = Guid.NewGuid().ToString();
            WriteToFile(saveDir, documentReport, fileID + ".docx");

            FileSize = GetFileLength(saveDir, fileID + ".docx");
            return fileID;
        }

        /// <summary>
        /// 生成批量报告
        /// </summary>
        /// <param name="ResultList"></param>
        /// <param name="ReportTemplate"></param>
        /// <param name="saveDir"></param>
        /// <param name="FileSize"></param>
        /// <returns></returns>
        public static string CreatMultiReport() // IQueryable<object> ResultList, string ReportTemplate, string saveDir, out string FileSize
        {
            // 批量处理时，样品定义中的发布属性要应用
            //FileSize = "";
            //if (!File.Exists(ReportTemplate))
            //    return "文件模板没找到！";

            //XWPFDocument documentReport;
            //using (FileStream fs = new FileStream(ReportTemplate, FileMode.Open, FileAccess.ReadWrite))
            //{
            //    documentReport = new XWPFDocument(fs);
            //}

            //WriteToTableCell(documentReport, ResultList);

            //var fileID = Guid.NewGuid().ToString();
            //WriteToFile(saveDir, documentReport, fileID + ".docx");

            //FileSize = GetFileLength(saveDir, fileID + ".docx");
            return "批量样品报告暂未定义模版！";
        }

        /// <summary>
        /// 填写数据表格内容
        /// </summary>
        /// <param name="documentReport"></param>
        /// <param name="ResultList"></param>
        private static string WriteToTableCell(XWPFDocument documentReport, IQueryable<object> ResultList)
        {
            int reCount = ResultList.Count(); // 列表的记录数
            int rowIndex = 1; // 填写表格时，跳过表头行
            int rows = documentReport.Tables[0].Rows.Count() - 1;

            foreach (var result in ResultList)
            {
                if (rowIndex > reCount)
                    break;

                var row = documentReport.Tables[0].Rows[rowIndex];
                var cells = row.GetTableCells();
                foreach (var cell in cells)
                {
                    try
                    {
                        var ptext = cell.Paragraphs[0].ParagraphText;
                        if (!string.IsNullOrEmpty(ptext))
                        {
#pragma warning disable CS8602 // 解引用可能出现空引用。
                            var retext = result.GetType().GetProperty(ptext).GetValue(result).ToString();
                            cell.Paragraphs[0].ReplaceText(ptext, retext);
#pragma warning restore CS8602 // 解引用可能出现空引用。
                        }
                    }
                    catch (Exception ex)
                    {
                        return ex.Message.ToString();
                    }
                }
                rowIndex++;
            }

            while (rowIndex <= rows) // 将表格剩余的行内容清空
            {
                var row = documentReport.Tables[0].Rows[rowIndex];
                var cells = row.GetTableCells();


                foreach (var cell in cells)
                {
                    var ptext = cell.Paragraphs[0].ParagraphText;
                    cell.Paragraphs[0].ReplaceText(ptext, "");
                }
                rowIndex++;
            }
            return "写入文件成功！";
        }

        /// <summary>
        /// 写入到文件
        /// </summary>
        /// <param name="dir"></param>
        /// <param name="documentOriginal"></param>
        /// <param name="FileName"></param>
        private static void WriteToFile(string dir, XWPFDocument documentOriginal, string FileName)
        {
            MemoryStream ms = new System.IO.MemoryStream();
            documentOriginal.Write(ms);

            DirectoryInfo savePath = new DirectoryInfo(dir);
            if (!savePath.Exists)
                Directory.CreateDirectory(dir);

            FileStream outfs = new FileStream(dir + FileName, FileMode.Create);
            BinaryWriter bw = new BinaryWriter(outfs);
            bw.Write(ms.GetBuffer());

            ms.Close();
            bw.Close();
            outfs.Close();
        }

        /// <summary>
        /// 获得指定文件的大小
        /// </summary>
        /// <param name="saveDir">文件存放路径</param>
        /// <param name="fileName">文件名</param>
        /// <returns></returns>
        private static string GetFileLength(string saveDir, string fileName)
        {
            var theFolder = new DirectoryInfo(saveDir); // 返回当前目录的的文件
            var files = theFolder.GetFiles();
            string size = "";

            foreach (var file in files)
            {
                if (file.Name == fileName)
                    size = GetSise(file.Length);
            }
            return size;
        }

        /// <summary>
        /// 计算文件大小
        /// </summary>
        /// <param name="filesize"></param>
        /// <returns></returns>
        private static string GetSise(long filesize)
        {
            if (filesize < 0)
                return "0";
            else if (filesize >= 1024 * 1024 * 1024)
                return string.Format("{0:0}GB", (double)filesize / (1024 * 1024 * 1024));
            else if (filesize >= 1024 * 1024)
                return string.Format("{0:0}MB", (double)filesize / (1024 * 1024));
            else if (filesize >= 1024)
                return string.Format("{0:0}KB", (double)filesize / (1024));
            else
                return string.Format("{0:0}bytes", filesize);
        }

    }
}
